package com.lex.security.config;

import com.lex.security.component.CustomAuthorizetionManager;
import com.lex.security.component.JwtAuthenticationTokenFilter;
import com.lex.security.component.RestAuthenticationEntryPoint;
import com.lex.security.component.RestfulAccessDeniedHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.util.AntPathMatcher;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class SecurityConfig {

    @Autowired
    private IgnoreUrlsConfig ignoreUrlsConfig;

    @Autowired
    private CustomAuthorizetionManager customAuthorizationManager;

    @Autowired
    private RestfulAccessDeniedHandler RestfulAccessDeniedHandler;

    @Autowired
    private RestAuthenticationEntryPoint restAuthenticationEntryPoint;


    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        //通过HttpSecurity 来配置url的访问控制规则
        AntPathMatcher matcher = new AntPathMatcher();
        //ant匹配
        httpSecurity.authorizeHttpRequests(customizer  -> {
            //antMatchers()方法用来匹配路径，permitAll()方法表示该路径不需要权限即可访问

            customizer.requestMatchers(
                    request -> ignoreUrlsConfig.getUrls().stream()
                            .anyMatch(url -> {
                                return matcher.match(url,request.getServletPath());
                            })
            ).permitAll();
            customizer.requestMatchers(
                    request -> "OPTIONS".equals(request.getMethod())
            ).permitAll();
            //所有请求都需要认证
            customizer.anyRequest().access(customAuthorizationManager);
        });
        //关闭csrf、session
        httpSecurity.csrf(AbstractHttpConfigurer::disable);
        httpSecurity.sessionManagement(AbstractHttpConfigurer::disable);
        httpSecurity.logout(AbstractHttpConfigurer::disable);
        //禁用缓存
        httpSecurity.headers(customizer -> customizer.cacheControl(
                HeadersConfigurer.CacheControlConfig::disable
        ));
        //添加JWT filter
        httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
        //添加自定义未授权和未登录结果返回
        httpSecurity.exceptionHandling(customizer -> customizer
                .accessDeniedHandler(RestfulAccessDeniedHandler)
                .authenticationEntryPoint(restAuthenticationEntryPoint)
        );
        return httpSecurity.build();

    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter(){
        return new JwtAuthenticationTokenFilter();
    }
}
